package com.demo01.client;

import com.demo01.core.DemoPacket;
import org.tio.client.intf.ClientAioHandler;
import org.tio.core.ChannelContext;
import org.tio.core.TioConfig;
import org.tio.core.exception.TioDecodeException;
import org.tio.core.intf.Packet;

import java.nio.ByteBuffer;

public class ClientDemoHandler implements ClientAioHandler {

    @Override
    public Packet heartbeatPacket(ChannelContext channelContext) {
        return null;
    }

    @Override
    public Packet decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws TioDecodeException {
        if (readableLength < DemoPacket.HEAD_LENGTH) {
            return null;
        }
        int bodyLength = buffer.getInt();
        if (bodyLength < 0) {
            throw new TioDecodeException("bodyLength [" + bodyLength + "] is not right, remote:" + channelContext.getClientNode());
        }
        int neededLength = DemoPacket.HEAD_LENGTH + bodyLength;
        int isDataEnough = readableLength - neededLength;
        if (isDataEnough < 0) {
            return null;
        } else {
            DemoPacket demoPacket = new DemoPacket();
            if (bodyLength > 0) {
                byte[] dst = new byte[bodyLength];
                buffer.get(dst);
                demoPacket.setBody(dst);
            }
            return demoPacket;
        }
    }

    @Override
    public ByteBuffer encode(Packet packet, TioConfig tioConfig, ChannelContext channelContext) {
        DemoPacket demoPacket = (DemoPacket) packet;
        byte[] body = demoPacket.getBody();

        int bodyLen = 0;
        if (body != null) {
            bodyLen = body.length;
        }
        int allLen = DemoPacket.HEAD_LENGTH + bodyLen;
        ByteBuffer buffer = ByteBuffer.allocate(allLen);
        buffer.order(tioConfig.getByteOrder());
        buffer.putInt(bodyLen);
        if (body != null) {
            buffer.put(body);
        }
        return buffer;
    }

    @Override
    public void handler(Packet packet, ChannelContext channelContext) throws Exception {
    }

}
